package com.sduept.nwld.wave.rest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sduept.bigdata.fault.manager.BreakerActionAnalysisManager;
import com.sduept.bigdata.fault.manager.FaultManager;
import com.sduept.bigdata.fault.manager.WaveFileManager;
import com.sduept.bigdata.fault.system.properties.FaultSystemProperties;
import com.sduept.cim.model.extend.CfgAnalogChannel;
import com.sduept.cim.model.extend.CfgDigitalChannel;
import com.sduept.cim.model.extend.ProtectWaveFile;
import com.sduept.cim.model.extend.WaveFile;
import com.sduept.cim.model.extend.protection.cfg.ProtectCfgAnalogChannel;
import com.sduept.cim.model.extend.protection.cfg.ProtectCfgDigitalChannel;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.wires.ACLineSegment;
import com.sduept.cim.model.wires.Breaker;
import com.sduept.cim.wave.service.CfgConfigureManager;
import com.sduept.cim.wave.service.ProtectCfgConfigureManager;
import com.sduept.cim.wave.service.ProtectWaveFileManager;
import com.sduept.common.tool.FileOpt;
import com.sduept.core.dao.SuperDAO;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.mobile.manager.MobileUtil;
import com.sduept.stardfile.parser.model.ChnInfo;
import com.sduept.stardfile.parser.model.DataInfo;
import com.sduept.stardfile.parser.model.cfg.CfgColumnNumException;
import com.sduept.stardfile.parser.model.cfg.CfgFile;
import com.sduept.stardfile.parser.model.cfg.CfgTimeFormatException;
import com.sduept.stardfile.parser.model.h5Comtrade.H5ChnSelectInfo;
import com.sduept.stardfile.parser.model.h5Comtrade.H5DataInfo;
import com.sduept.stardfile.parser.tool.ComtradeFiles;
import com.sduept.stardfile.parser.util.H5ComtradeUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.inject.Inject;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * 波形数据REST服务
 * @author Ningfw
 * @date 2017-06-15
 *
 */
@RestController
@RequestMapping("/waveData/")
public class WaveDataServices {

	@Autowired
	private SuperDAO superDao;
	@Autowired
	private FaultManager faultManager;//根据lineId、faultTime获取faultFileId
	@Autowired
	private CimManager cm;
	@Autowired
	private WaveFileManager wa;
	@Autowired
	private CfgConfigureManager cfManager;
	@Autowired
	private BreakerActionAnalysisManager baam;
	@Autowired
	private ProtectWaveFileManager pwfm;
	@Autowired
	private ProtectCfgConfigureManager pccfm;
	@Inject
	private MobileUtil mobileUtil;//SQL注入检测类
	@Autowired
	private FaultSystemProperties pros;
	/**
	 * 获取波形数据，六个为一组
	 * @return
	 */

	@GetMapping("/getWaveData/{fileId}/{lineId}")
	public String getWaveData(@PathVariable("fileId") String fileId,@PathVariable("lineId") String lineId){
		
		String sqlWave = "SELECT lw.pre_fault_wave_data,lw.post_fault_wave_data,lw.reclose_wave_data FROM t_lbtz_line_wave_data lw WHERE lw.fault_file_id = '"+fileId+"' "
				+ "AND lw.line_id = '"+lineId+"'";
		List<?> waveList = superDao.nativeQuery(sqlWave);
		StringBuffer waveStr = new StringBuffer();
		for(Object obj : waveList){//故障前、故障后、重合闸拼接
			Object[] objs = (Object[]) obj;
			for(int i=0; i < objs.length; i++){
				if(0 == i){
					waveStr.append(objs[i].toString().replace("\n", ",").replaceAll("\\s*", ""));//\n替换为,
				}else{
					waveStr.append(objs[i].toString().replace("\n", ",").replaceAll("\\s*", ""));//\n替换为,
				}
			}
		}
		String wave = waveStr.toString();//\n替换为,然后分组
		String[] arr = wave.split(",");
		
		JSONObject jso = new JSONObject();
		JSONArray jsa = new JSONArray();//总波形
		JSONArray jsa1 = new JSONArray();//第一条波
		BigDecimal max1 = new BigDecimal(0);
		BigDecimal min1 = new BigDecimal(0);
		JSONArray jsa2 = new JSONArray();//第二条波
		BigDecimal max2 = new BigDecimal(0);
		BigDecimal min2 = new BigDecimal(0);
		JSONArray jsa3 = new JSONArray();//第三条波
		BigDecimal max3 = new BigDecimal(0);
		BigDecimal min3 = new BigDecimal(0);
		JSONArray jsa4 = new JSONArray();//第四条波
		BigDecimal max4 = new BigDecimal(0);
		BigDecimal min4 = new BigDecimal(0);
		JSONArray jsa5 = new JSONArray();//第五条波
		BigDecimal max5 = new BigDecimal(0);
		BigDecimal min5 = new BigDecimal(0);
		JSONArray jsa6 = new JSONArray();//第六条波
		BigDecimal max6 = new BigDecimal(0);
		BigDecimal min6 = new BigDecimal(0);
		JSONArray xAxis = new JSONArray();//数组中x轴的值
		for(int i = 0; i < arr.length/8; i++){
			jsa1.add(kepBit(arr[i*8 + 2]));//第一条波：需要数据库中3/11/19...，数组从0开始，所以需要2/10/18...
			max1 = findMax(max1, kepBit(arr[i*8 + 2]));
			min1 = findMin(min1, kepBit(arr[i*8 + 2]));
			jsa2.add(kepBit(arr[i*8 + 3]));
			max2 = findMax(max2, kepBit(arr[i*8 + 3]));
			min2 = findMin(min2, kepBit(arr[i*8 + 3]));
			jsa3.add(kepBit(arr[i*8 + 4]));
			max3 = findMax(max3, kepBit(arr[i*8 + 4]));
			min3 = findMin(min3, kepBit(arr[i*8 + 4]));
			jsa4.add(kepBit(arr[i*8 + 5]));
			max4 = findMax(max4, kepBit(arr[i*8 + 5]));
			min4 = findMin(min4, kepBit(arr[i*8 + 5]));
			jsa5.add(kepBit(arr[i*8 + 6]));
			max5 = findMax(max5, kepBit(arr[i*8 + 6]));
			min5 = findMin(min5, kepBit(arr[i*8 + 6]));
			jsa6.add(kepBit(arr[i*8 + 7]));
			max6 = findMax(max6, kepBit(arr[i*8 + 7]));
			min6 = findMin(min6, kepBit(arr[i*8 + 7]));
			xAxis.add(new BigDecimal(arr[i*8 + 1]).subtract(new BigDecimal(60000)));//x轴减去60000
		}
		
		BigDecimal maxVol = (max1.subtract(min1)).abs();//求Ua/Ub/Uc中高度差最大的
		if(maxVol.compareTo((max2.subtract(min2)).abs()) == -1){
			maxVol = (max2.subtract(min2)).abs();
		}
		if(maxVol.compareTo((max3.subtract(min3)).abs()) == -1){
			maxVol = (max3.subtract(min3)).abs();
		}
		
		BigDecimal halfMaxVol = maxVol;//最大电压差波的1/25
//		BigDecimal halfMaxVol = maxVol.divide(new BigDecimal(2),0,BigDecimal.ROUND_HALF_EVEN);//最大电压差波的1/25
		BigDecimal divideHeight = maxVol.divide(new BigDecimal(25),2,BigDecimal.ROUND_HALF_EVEN);//最大电压差波的1/25
		
		JSONArray height = new JSONArray();//波形加的高度

		BigDecimal bgU1 = max1.subtract(min1);//取第一条电压的高度差，电流全部乘第一条电压的高度差
		BigDecimal maxAbs = (max4.subtract(min4)).abs();//求Ia/Ib/Ic中高度差最大的
		if(maxAbs.compareTo((max5.subtract(min5)).abs()) == -1){
			maxAbs = (max5.subtract(min5)).abs();
		}
		if(maxAbs.compareTo((max6.subtract(min6)).abs()) == -1){
			maxAbs = (max6.subtract(min6)).abs();
		}
		BigDecimal rateI = bgU1.divide(maxAbs,0,BigDecimal.ROUND_HALF_UP);//Ia/Ib/Ic乘相同的倍数
		
		max6 = max6.multiply(rateI);//最大值乘倍数
		min6 = min6.multiply(rateI);//最小值乘倍数
		for(int i = 0; i < jsa6.size(); i++){//高度加1个高度差
			String valueNow = (new BigDecimal(jsa6.getString(i))).multiply(rateI).toPlainString();//现值乘倍数
			String value = addHeight(valueNow, halfMaxVol);
			jsa6.set(i, value);
		}
		
		max5 = max5.multiply(rateI);//最大值乘倍数
		min5 = min5.multiply(rateI);//最小值乘倍数
		for(int i = 0; i < jsa5.size(); i++){//高度加2个高度差加1个波形最大差值的1/25
			String valueNow = (new BigDecimal(jsa5.getString(i))).multiply(rateI).toPlainString();//现值乘倍数
			String value = addHeight(valueNow, halfMaxVol.multiply(new BigDecimal("2")).add(divideHeight));
			jsa5.set(i, value);
		}
		
		max4 = max4.multiply(rateI);//最大值乘倍数
		min4 = min4.multiply(rateI);//最小值乘倍数
		for(int i = 0; i < jsa4.size(); i++){//高度加3个高度差加2个波形最大差值的1/25
			String valueNow= (new BigDecimal(jsa4.getString(i))).multiply(rateI).toPlainString();//现值乘倍数
			String value = addHeight(valueNow, halfMaxVol.multiply(new BigDecimal("3")).add(divideHeight.multiply(new BigDecimal("2"))));
			jsa4.set(i, value);
		}
		
		for(int i = 0; i < jsa3.size(); i++){//高度加4个高度差加3个波形最大差值的1/25
			jsa3.set(i, addHeight(jsa3.getString(i), halfMaxVol.multiply(new BigDecimal("4")).add(divideHeight.multiply(new BigDecimal("3")))));
		}
		
		for(int i = 0; i < jsa2.size(); i++){//高度加5个高度差加4个波形最大差值的1/25
			jsa2.set(i, addHeight(jsa2.getString(i),halfMaxVol.multiply(new BigDecimal("5")).add(divideHeight.multiply(new BigDecimal("4")))));
		}
		
		for(int i = 0; i < jsa1.size(); i++){//高度加6个高度差加5个波形最大差值的1/25
			jsa1.set(i, addHeight(jsa1.getString(i), halfMaxVol.multiply(new BigDecimal("6")).add(divideHeight.multiply(new BigDecimal("5")))));
		}
		
		jsa.add(jsa1);
		jsa.add(jsa2);
		jsa.add(jsa3);
		jsa.add(jsa4);
		jsa.add(jsa5);
		jsa.add(jsa6);

		height.add(halfMaxVol.multiply(new BigDecimal("6")).add(divideHeight.multiply(new BigDecimal("5"))));
		height.add(halfMaxVol.multiply(new BigDecimal("5")).add(divideHeight.multiply(new BigDecimal("4"))));
		height.add(halfMaxVol.multiply(new BigDecimal("4")).add(divideHeight.multiply(new BigDecimal("3"))));
		height.add(halfMaxVol.multiply(new BigDecimal("3")).add(divideHeight.multiply(new BigDecimal("2"))));
		height.add(halfMaxVol.multiply(new BigDecimal("2")).add(divideHeight));
		height.add(halfMaxVol);
		
		String[] nameArr = {"Ua","Ub","Uc","Ia","Ib","Ic"};
		int[] rateArr = {1,1,1,rateI.intValue(),rateI.intValue(),rateI.intValue()};//电流所放大比例
		
		jso.put("wave", jsa);//y轴
		jso.put("height", height);//高度
		jso.put("xAxis", xAxis);//x轴
		jso.put("rate", rateArr);//电流所乘比例
		jso.put("name", nameArr);//name
		return jso.toJSONString();
	}
	
	/**
	 * String转BigDecimal
	 * @param str
	 * @return
	 */
	public String toPlainString(String str){
		String plainStr = "0";
		if(null != str && " " != str && !" ".equals(str) && "" != str && !"".equals(str)){
			BigDecimal bg = new BigDecimal(str);
			plainStr = bg.toPlainString();
		}
		return plainStr;
	}
	
	/**
	 * 保留有效位
	 * @param str
	 * @return
	 */
	public String kepBit(String str){
		if(null != str && !"".equals(str)){
			BigDecimal bd = new BigDecimal(str);
			String res = bd.setScale(3, BigDecimal.ROUND_HALF_UP).toString();
			return res;
		}else{
			return null;
		}
	}
	
	/**
	 * 比较返回最大值
	 * @param bg
	 * @param bgd
	 * @return
	 */
	public BigDecimal findMax(BigDecimal bg, String bgd){
		BigDecimal bd = new BigDecimal(bgd);
		if(bg.compareTo(bd) == -1){//bd大
			return bd;
		}else{
			return bg;
		}
	}
	
	/**
	 * 比较返回最小值
	 * @param bg
	 * @param bgd
	 * @return
	 */
	public BigDecimal findMin(BigDecimal bg, String bgd){
		BigDecimal bd = new BigDecimal(bgd);
		if(bg.compareTo(bd) == 1){//bd小
			return bd;
		}else{
			return bg;
		}
	}
	
	/**
	 * 数据添加高度差
	 * @param str
	 * @param bgd
	 * @return
	 */
	public String addHeight(String str, BigDecimal bgd){
		BigDecimal bg = new BigDecimal(str);
		BigDecimal bd = bg.add(bgd);
		return bd.toPlainString();
	}
	
	/**
	 * 获取所有的断路器动作返回
	 * @return [[line_name,fault_file_id,breaker_name,breaker_id,first_action_phase,actTime,faultTime]]
	 */

    @GetMapping("/getBreakerAllActionDatas")
	public String getBreakerAllActionDatas() {
		List<String[]> ws = baam.getBreakerActionInfo();
		JSONArray rtn = new JSONArray();
		for(String[] d : ws){
			rtn.add(d);
		}
        return rtn.toJSONString();
    }

	/**
	 * 获取保护最早动作时间
	 * @return 
	 */

    @GetMapping("/getMinProtectActTime/{fileId}/{phase}")
	public String getMinProtectActTime(@PathVariable("fileId") String fileId,@PathVariable("phase") String phase) {
		String sqlStr="select min(distance_0_moments_time) from t_protection_action_info where fault_file_id ='"+fileId+"' and phase='"+phase+"'";
		List<?> objs=superDao.nativeQuery(sqlStr);
		Object os=(Object)objs.get(0);
		if(os == null) {
			os = "";
		}
        return os.toString();
    }
	
	/**
	 * 第一个是原始波形，后面5条是分解后的小波波形
	 * @param fileId
	 * @param breakerId
	 * @return {"preFault":[[],[]],"postFault":[[],[]]}
	 */

    @GetMapping("/getBreakerWaveLetData/{fileId}/{breakerId}/{phase}")
	public String getWaveLetData(@PathVariable("fileId") String fileId,@PathVariable("breakerId") String breakerId,@PathVariable("phase") String phase) {
		double[][] posWS = baam.getPostFaultWaveletData(fileId, breakerId,phase);
		double[][] preWS = baam.getPreFaultWaveletData(fileId, breakerId,phase);
		net.sf.json.JSONObject jso=new net.sf.json.JSONObject();
		JSONArray preRtn = new JSONArray();
		if(preWS!=null){
			for(double[] d : preWS){
				preRtn.add(d);
			}
			jso.put("preFault", preRtn);
		}
		JSONArray postRtn = new JSONArray();
		if(posWS !=null){
			for(double[] d : posWS){
				postRtn.add(d);
			}
			jso.put("postFault", postRtn);
		}
        return jso.toString();
    }
	/**
	 * 前台展示波形数据来源。
	 * 必选参数：
	 * type: 1 表示集中录波  2 表示保护录波
	 * fileId: 文件id
	 * allSelector：前台进行的通道选择
	 * 可选参数：
	 * initParams：初始化时，后台自动进行通道选择时调用的参数。目前只有集中录波需要配置这个值。
	 * 对于集中录波来说，这个值是一个json对象的字符串形式。里面需要stationId和lineId
	 * @param params
	 * @return
	 */

	@PostMapping("/getWaveH5DataInfo")
	public String getWaveH5DataInfo(@RequestBody String params){
		JSONObject p = JSONObject.parseObject(params);
		String type = p.getString("type");//集中录波是1 保护录波是2
		String fileId = p.getString("fileId");
		String initParams = p.getString("initParams");
		String allSelector = p.getString("allSelector");
		
		int[] chnSelectInfoArray = null;
		if(StringUtils.isNoneEmpty(allSelector)){
			List<Integer> chnSelectInfoList = JSONArray.parseArray(allSelector, Integer.class);
			if(chnSelectInfoList.size() > 0){
				chnSelectInfoArray = new int[chnSelectInfoList.size()];
				for(int i=0;i<chnSelectInfoArray.length;i++) {
					if(chnSelectInfoList.get(i) != null) {
						chnSelectInfoArray[i] = chnSelectInfoList.get(i).intValue();
					}
				}
			}
		}
		//首先判断是哪种录波。判断完之后，调用不同录波的方法，拿到数据
		if(StringUtils.isEmpty(type)){
			type = getWaveType(fileId);
		}
		H5DataInfo info = null;
		switch (type) {
		case "1":
			info = getBxWaveH5DataInfo(fileId,chnSelectInfoArray,initParams);
			break;
		case "2":
			info = getProtectWaveH5DataInfo(fileId,chnSelectInfoArray);
			break;
		default:
			break;
		}
		return JSONObject.toJSONString(info);
	}
	@PostMapping("/getWaveH5DataInfo4POST")
	public String getWaveH5DataInfo4POST(String stationId, String lineId, String fileId, String type, String allSelector){
		try {
			/*urlp = URLDecoder.decode(params, "utf-8");
			log.info(urlp);
			JSONObject p = JSONObject.parseObject(urlp);
			String type = p.getString("type");//集中录波是1 保护录波是2
			String fileId = p.getString("fileId");
			String initParams = p.getString("initParams");
			String allSelector = p.getString("allSelector")*/;
			stationId = mobileUtil.SQLInjectCheck(stationId);
			lineId = mobileUtil.SQLInjectCheck(lineId);
			fileId = mobileUtil.SQLInjectCheck(fileId);
			type = mobileUtil.SQLInjectCheck(type);
			allSelector = mobileUtil.SQLInjectCheck(allSelector);
			JSONObject initParams=new JSONObject();
		    initParams.put("stationId",stationId);
		    initParams.put("lineId",lineId);
			String decodeSe="";
			try {
				decodeSe=allSelector;
			} catch (Exception e) {
				e.printStackTrace();
			}
			int[] chnSelectInfoArray = null;
			if(StringUtils.isNoneEmpty(decodeSe)){
				List<Integer> chnSelectInfoList = JSONArray.parseArray(decodeSe, Integer.class);
				if(chnSelectInfoList.size() > 0){
					chnSelectInfoArray = new int[chnSelectInfoList.size()];
					for(int i=0;i<chnSelectInfoArray.length;i++) {
						if(chnSelectInfoList.get(i) != null) {
							chnSelectInfoArray[i] = chnSelectInfoList.get(i).intValue();
						}
					}
				}
			}
			//首先判断是哪种录波。判断完之后，调用不同录波的方法，拿到数据
			if(StringUtils.isEmpty(type)){
				type = getWaveType(fileId);
			}
			H5DataInfo info = null;
			switch (type) {
			case "1":
				info = getBxWaveH5DataInfo(fileId,chnSelectInfoArray,initParams.toString());
				break;
			case "2":
				info = getProtectWaveH5DataInfo(fileId,chnSelectInfoArray);
				break;
			default:
				break;
			}
			return JSONObject.toJSONString(info);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	private String getWaveType(String fileId){
		WaveFile file = wa.getWaveFileById(fileId);
		if(file == null){
			return "2";
		}else{
			return "1";
		}
	}
	/**
	 * 得到集中录波的文件信息
	 * @param fileId
	 * @param stationId
	 * @param lineId
	 * @param selectInfo
	 * @return
	 */
	private H5DataInfo getBxWaveH5DataInfo(String fileId,H5ChnSelectInfo[] selectInfo,String initParams){
		WaveFile file = wa.getWaveFileById(fileId);
		if(file != null){
			String filePath = pros.getWaveFilePath()+file.getPath();
			File f = new File(filePath+".cfg");
			if(f.exists()){
				int[] initSelectAnalogs = null;
				int[] initSelectDigitals = null;
				if(selectInfo == null && StringUtils.isNoneEmpty(initParams)){//当selectInfo是null的时候，去拿默认值
					JSONObject p = JSONObject.parseObject(initParams);
					String stationId = p.getString("stationId");
					String lineId = p.getString("lineId");
					if(StringUtils.isNotEmpty(lineId) && StringUtils.isNotEmpty(stationId)){
						initSelectAnalogs = getBxWaveInitSelectAnalogs(lineId,stationId,file.getEquipId());
						initSelectDigitals = getBxWaveInitSelectDigitals(lineId,stationId,file.getEquipId());
					}
					/*//默认通道加载失败时，选择所有通道
					if(initSelectAnalogs == null || initSelectAnalogs.length == 0) {
						CfgFile cfgFile = readCfgFile(filePath);
						initSelectAnalogs = getIncreaseArray(cfgFile.A);
						initSelectDigitals = getIncreaseArray(cfgFile.D);
					}*/
				}
				H5DataInfo info = H5ComtradeUtil.getComtradeData(filePath, selectInfo, initSelectAnalogs, initSelectDigitals, null, true, 2048*1024);
				return info;
			}
		}
		return null;
	}
	/**
	 * 得到集中录波的文件信息
	 * @param fileId
	 * @param stationId
	 * @param lineId
	 * @param selectInfo
	 * @return
	 */
	private H5DataInfo getBxWaveH5DataInfo(String fileId,int[] selectInfo,String initParams){
		WaveFile file = wa.getWaveFileById(fileId);
		if(file != null){
			String filePath = pros.getWaveFilePath()+file.getPath();
			File f = new File(filePath+".cfg");
			if(f.exists()){
				int[] initSelectAnalogs = null;
				int[] initSelectDigitals = null;
				if(selectInfo == null && StringUtils.isNoneEmpty(initParams)){//当selectInfo是null的时候，去拿默认值
					JSONObject p = JSONObject.parseObject(initParams);
					String stationId = p.getString("stationId");
					String lineId = p.getString("lineId");
					if(StringUtils.isNotEmpty(lineId) && StringUtils.isNotEmpty(stationId)){
						initSelectAnalogs = getBxWaveInitSelectAnalogs(lineId,stationId,file.getEquipId());
						initSelectDigitals = getBxWaveInitSelectDigitals(lineId,stationId,file.getEquipId());
					}
				}
				H5DataInfo info = H5ComtradeUtil.getComtradeData(filePath, selectInfo, initSelectAnalogs, initSelectDigitals, null, true, 2048*1024);
				return info;
			}
		}
		return null;
	}
	/**
	 * 获得一个大小为size的递增数组。[1,2,3,...,size]
	 * @param size
	 * @return
	 */
	private int[] getIncreaseArray(int size) {
		int[] arr = new int[size];
		for(int i=0;i<size;i++) {
			arr[i] = i+1;
		}
		return arr;
	}
	private CfgFile readCfgFile(String path) {
		InputStream stream = null;
		try {
			stream = new FileInputStream(path+".cfg");
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		String data = null;
		try {
			data = IOUtils.toString(stream);
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		CfgFile cfgFile = new CfgFile();
		try {
			cfgFile.ReadCfgFile(data);
		} catch (NumberFormatException | IndexOutOfBoundsException | CfgColumnNumException
				| CfgTimeFormatException e1) {
			e1.printStackTrace();
		}
		return cfgFile;
	}
	
	/**
	 * 得到保护录波的文件信息
	 * @param fileId
	 * @param stationId
	 * @param lineId
	 * @param selectInfo
	 * @return
	 */
	private H5DataInfo getProtectWaveH5DataInfo(String fileId,H5ChnSelectInfo[] selectInfo ){
		ProtectWaveFile file = pwfm.getProtectWaveFile(fileId);
		if(file != null){
			String filePath = pros.getWaveFilePath()+file.getPath();
			File f = new File(filePath+".cfg");
			if(f.exists()){
				int[] initSelectAnalogs = null;
				int[] initSelectDigitals = null;
				if(selectInfo == null){//当selectInfo是null的时候，去拿默认值
					initSelectAnalogs = getProtectWaveInitSelectAnalogs(file.getEquipId());
					initSelectDigitals = getProtectWaveInitSelectDigitals(file.getEquipId());
				}
				H5DataInfo info = H5ComtradeUtil.getComtradeData(filePath, selectInfo, initSelectAnalogs, initSelectDigitals, null, true, 2048*1024);
				return info;
			}
		}
		return null;
	}
	/**
	 * 得到保护录波的文件信息
	 * @param fileId
	 * @param stationId
	 * @param lineId
	 * @param selectInfo
	 * @return
	 */
	private H5DataInfo getProtectWaveH5DataInfo(String fileId,int[] selectInfo ){
		ProtectWaveFile file = pwfm.getProtectWaveFile(fileId);
		if(file != null){
			String filePath = pros.getWaveFilePath()+file.getPath();
			File f = new File(filePath+".cfg");
			if(f.exists()){
				int[] initSelectAnalogs = null;
				int[] initSelectDigitals = null;
				if(selectInfo == null){//当selectInfo是null的时候，去拿默认值
					initSelectAnalogs = getProtectWaveInitSelectAnalogs(file.getEquipId());
					initSelectDigitals = getProtectWaveInitSelectDigitals(file.getEquipId());
				}
				H5DataInfo info = H5ComtradeUtil.getComtradeData(filePath, selectInfo, initSelectAnalogs, initSelectDigitals, null, true, 2048*1024);
				return info;
			}
		}
		return null;
	}
	/**
	 * 集中录波的模拟量通道号。包括线路和变电站对应的电压电流模拟量通道号，以及开关对应的电流模拟量通道号。
	 * @param lineId
	 * @param stationId
	 * @param waveFile
	 * @return
	 */
	private int[] getBxWaveInitSelectAnalogs(String eid,String stationId,String waveEquipId){
		//waveFile != null
		List<Integer> channelNumbers = new ArrayList<Integer>();
		//根据线路找到对应的开关
		List<Breaker> breakers = cm.getBreakersById(eid, stationId);
		//根据线路找（模拟通道）表中的线路关联的电压、电流通道号，根据开关找到 的电流通道号
		List<CfgAnalogChannel> list1 = cfManager.listChannelsByConditions(stationId, eid, "V",waveEquipId);
		for(CfgAnalogChannel channel:list1){
			channelNumbers.add(channel.getNo());
		}
		List<CfgAnalogChannel> list2 = cfManager.listChannelsByConditions(stationId, eid, "A",waveEquipId);
		for(CfgAnalogChannel channel:list2){
			channelNumbers.add(channel.getNo());
		}
		for(Breaker b:breakers){
			List<CfgAnalogChannel> aList= cfManager.listChannelsByConditions(stationId, b.getId(), "A",waveEquipId);
			for(CfgAnalogChannel channel:aList){
				channelNumbers.add(channel.getNo());
			}
		}
		int[] numbers = new int[channelNumbers.size()];
		for(int i=0;i<channelNumbers.size();i++){
			numbers[i] = channelNumbers.get(i).intValue();
		}
		return numbers;
	}
	/**
	 * 集中录波的模拟量通道号。
	 * 包括线路和变电站对应的电压电流模拟量通道号，以及开关对应的电流模拟量通道号。
	 * @param lineId
	 * @param stationId
	 * @param waveFile
	 * @return
	 */
	private int[] getBxWaveInitSelectDigitals(String eid,String stationId,String waveEquipId){
		List<Integer> digNumbers=new ArrayList<Integer>();
	
		List<Breaker> breakers = cm.getBreakersById(eid, stationId);
		for(Breaker b:breakers){
			List<CfgDigitalChannel> list = cfManager.listCfgDigitalChannelsByEquipementId(b.getId());
			for(CfgDigitalChannel channel:list){
				digNumbers.add(channel.getNo());
			}
		}
		List<ProtectionEquipment> listEquipments = cm.listsByStationIdAndProtectedId(stationId,eid);
		for(ProtectionEquipment pro:listEquipments){
			List<CfgDigitalChannel> channels = cfManager.listDiChannelsByConditions(stationId, pro.getId(),waveEquipId);
			for(CfgDigitalChannel channel:channels){
				digNumbers.add(channel.getNo());
			}
		}
		int[] numbers = new int[digNumbers.size()];
		for(int i=0;i<digNumbers.size();i++){
			numbers[i] = digNumbers.get(i).intValue();
		}
		return numbers;
	}
	/**
	 * 根据保护id，拿到保护对应的模拟量通道号
	 * @param ptId
	 * @return
	 */
	private int[] getProtectWaveInitSelectAnalogs(String ptId){
		List<ProtectCfgAnalogChannel> list = pccfm.listProtectCfgAnalogChannelsByPtId(ptId);
		List<Integer> analogNumbers = new ArrayList<>();
		for(int i=0;i<list.size();i++){
			if(StringUtils.isNotEmpty(list.get(i).getEquipmentId())){
				analogNumbers.add(list.get(i).getNo());
			}
		}
		int[] numbers = new int[analogNumbers.size()];
		for(int i=0;i<analogNumbers.size();i++){
			numbers[i] = analogNumbers.get(i).intValue();
		}
		return numbers;
	}
	/**
	 * 根据保护id，拿到保护对应的数字量通道号
	 * @param ptId
	 * @return
	 */
	private int[] getProtectWaveInitSelectDigitals(String ptId){
		List<ProtectCfgDigitalChannel> list = pccfm.listProtectCfgDigitalChannelsByPtId(ptId);
		List<Integer> digitalNumbers = new ArrayList<>();
		for(int i=0;i<list.size();i++){
			if(StringUtils.isNotEmpty(list.get(i).getEquipmentId())){
				digitalNumbers.add(list.get(i).getNo());
			}
		}
		int[] numbers = new int[digitalNumbers.size()];
		for(int i=0;i<digitalNumbers.size();i++){
			numbers[i] = digitalNumbers.get(i).intValue();
		}
		return numbers;
	}

	@GetMapping("/getCfg/{type}/{fileId}")
	public String getCfg(@PathVariable("type") String type,@PathVariable("fileId") String fileId){
		//先判断是集中录波还是保护录波，再去不同的表里找到文件位置
		if(StringUtils.isEmpty(type) || type.equals("undefined")){
			type = getWaveType(fileId);
		}
		String  filePath = null;
		if("1".equals(type)){
			WaveFile file = wa.getWaveFileById(fileId);
			if(file != null){
				filePath = pros.getWaveFilePath()+file.getPath();
			}
		}else{
			ProtectWaveFile file = pwfm.getProtectWaveFile(fileId);
			if(file != null){
				filePath = pros.getWaveFilePath()+file.getPath();
			}
		}
		if(filePath != null){
			JSONObject jsonObject = new JSONObject();
			try {
				jsonObject.put("content", FileOpt.readToString(filePath+".cfg", "gbk"));
			} catch (FileNotFoundException e) {
				jsonObject.put("error", filePath+".cfg 文件不存在");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return jsonObject.toJSONString();
		}
		return null;
	}

	@GetMapping("/getWaveDataFromFile/{fileId}/{stationId}/{lineId}")
	public String getWaveDataFromFile(@PathVariable("fileId") String fileId,@PathVariable("stationId") String stationId,@PathVariable("lineId") String lineId) {
		List<String> channelVNumbers=new ArrayList<String>();
		List<String> channelANumbers=new ArrayList<String>();
		//根据开关找到 数字通道中的通道号，根据线路找到线路对应的保护设备对应的通道号
		List<String> digNumbers=new ArrayList<String>();
		//根据lineId 找到线路
		ACLineSegment acLine = cm.getAcLineSegmentById(lineId);
		//根据fileID 找到文件位置
		WaveFile waveFile = wa.getWaveFileById(fileId);
		if(acLine != null && waveFile != null){
			//根据线路找到对应的开关
			List<Breaker> breakers = cm.getBreakersById(acLine.getId(), stationId);
			//根据线路找（模拟通道）表中的线路关联的电压、电流通道号，根据开关找到 的电流通道号
			List<CfgAnalogChannel> list1 = cfManager.listChannelsByConditions(stationId, acLine.getId(), "V",waveFile.getEquipId());
			for(CfgAnalogChannel channel:list1){
				channelVNumbers.add(String.valueOf(channel.getNo()));
			}
			List<CfgAnalogChannel> list2 = cfManager.listChannelsByConditions(stationId, acLine.getId(), "A",waveFile.getEquipId());
			for(CfgAnalogChannel channel:list2){
				channelANumbers.add(String.valueOf(channel.getNo()));
			}
			for(Breaker b:breakers){
				List<CfgAnalogChannel> aList= cfManager.listChannelsByConditions(stationId, b.getId(), "A",waveFile.getEquipId());
				for(CfgAnalogChannel channel:aList){
					channelANumbers.add(String.valueOf(channel.getNo()));
				}
			}
			for(Breaker b:breakers){
				List<CfgDigitalChannel> list = cfManager.listCfgDigitalChannelsByEquipementId(b.getId());
				for(CfgDigitalChannel channel:list){
					digNumbers.add(String.valueOf(channel.getNo()));
				}
			}
			List<ProtectionEquipment> listEquipments = cm.listsByStationIdAndProtectedId(stationId,acLine.getId());
			for(ProtectionEquipment pro:listEquipments){
				List<CfgDigitalChannel> channels = cfManager.listDiChannelsByConditions(stationId, pro.getId(),waveFile.getEquipId());
				for(CfgDigitalChannel channel:channels){
					digNumbers.add(String.valueOf(channel.getNo()));
				}
			}
		}
		String  volchns ="";
		for(int i=0;i<channelVNumbers.size();i++){
			if(i<channelVNumbers.size()-1){
				volchns=volchns+channelVNumbers.get(i)+",";
			}else{
				volchns=volchns+channelVNumbers.get(i);
			}
		}
		String  curchns = "";
		for(int j=0;j<channelANumbers.size();j++){
			if(j<channelANumbers.size()-1){
				curchns=curchns+channelANumbers.get(j)+",";
			}else{
				curchns=curchns+channelANumbers.get(j);
			}
		}
	
		String  dchns = "";
		for(int k=0;k<digNumbers.size();k++){
			if(k<digNumbers.size()-1){
				dchns=dchns+digNumbers.get(k)+",";
			}else{
				dchns=dchns+digNumbers.get(k);
			}
		}
		String filePath = pros.getWaveFilePath()+waveFile.getPath();
		int[] chnNo = new int[]{};
		int begin = 0;
		int xStep = 1;
		int left = 0;
		int right = 0;
		JSONObject obj = getWaveJson(filePath,chnNo,begin,xStep,left,right,volchns,curchns,dchns);
		return obj.toJSONString();
	}

	@GetMapping("/getBhWaveDataFromFile/{fileId}/{stationId}/{lineId}")
	public String getBhWaveDataFromFile(@PathVariable("fileId") String fileId,@PathVariable("stationId") String stationId,@PathVariable("lineId") String lineId) {
		ProtectWaveFile waveFile=pwfm.getProtectWaveFile(fileId);
		List<String> channelVNumbers=new ArrayList<String>();
		List<String> channelANumbers=new ArrayList<String>();
		//根据开关找到 数字通道中的通道号，根据线路找到线路对应的保护设备对应的通道号
		List<String> digNumbers=new ArrayList<String>();
		if(waveFile != null){
			//根据线路找（模拟通道）表中的线路关联的电压、电流通道号，根据开关找到 的电流通道号
			List<ProtectCfgAnalogChannel> list1 =  pccfm.listProtectCfgAnalogChannelsByPtId(waveFile.getEquipId());;
			for(ProtectCfgAnalogChannel channel:list1){
				if("V".equals(channel.getType()))
					channelVNumbers.add(String.valueOf(channel.getNo()));
				else if("A".equals(channel.getType()))
					channelANumbers.add(String.valueOf(channel.getNo()));
			}
			List<ProtectCfgDigitalChannel> channels = pccfm.listProtectCfgDigitalChannelsByPtId(waveFile.getEquipId());
			for(ProtectCfgDigitalChannel channel:channels){
				digNumbers.add(String.valueOf(channel.getNo()));
			}
		}
		String  volchns ="";
		for(int i=0;i<channelVNumbers.size();i++){
			if(i<channelVNumbers.size()-1){
				volchns=volchns+channelVNumbers.get(i)+",";
			}else{
				volchns=volchns+channelVNumbers.get(i);
			}
		}
		String  curchns = "";
		for(int j=0;j<channelANumbers.size();j++){
			if(j<channelANumbers.size()-1){
				curchns=curchns+channelANumbers.get(j)+",";
			}else{
				curchns=curchns+channelANumbers.get(j);
			}
		}
		
		String  dchns = "";
		for(int k=0;k<digNumbers.size();k++){
			if(k<digNumbers.size()-1){
				dchns=dchns+digNumbers.get(k)+",";
			}else{
				dchns=dchns+digNumbers.get(k);
			}
		}
		String filePath = pros.getWaveFilePath()+waveFile.getPath();
		int[] chnNo = new int[]{};
		int begin = 0;
		int xStep = 1;
		int left = 0;
		int right = 0;
		JSONObject obj = getWaveJson(filePath,chnNo,begin,xStep,left,right,volchns,curchns,dchns);
		return obj.toJSONString();
	}
	private JSONObject getWaveJson(String fileName,int[] chnNo,int begin,int xStep,int left,int right,
    		String volChns,String curChns,String digChns){
		ComtradeFiles comtrade = new ComtradeFiles();
		DataInfo dataInfo = comtrade.getDataInfoNoDefault(fileName,chnNo,begin,xStep,left,right,volChns,curChns,digChns);
		JSONObject jo = new JSONObject();
		jo.put("beginTime", dataInfo.time);
		JSONArray ja = new JSONArray();
		for(ChnInfo chnInfo : dataInfo.chnInfo){
			JSONObject jo1 = new JSONObject();
			jo1.put("name", chnInfo.chn_name);
			jo1.put("uu", chnInfo.uu);
			jo1.put("ps", chnInfo.ps);
			jo1.put("analyse", chnInfo.analyse);
			jo1.put("skew", chnInfo.skew);
			jo1.put("ptct", chnInfo.ptct);
			jo1.put("a", chnInfo.a);
			jo1.put("b", chnInfo.b);
			jo1.put("max", chnInfo.chn_max);
			jo1.put("y", JSONArray.toJSON(chnInfo.chn_pos));
			jo1.put("cursor", chnInfo.left_value);
			jo1.put("cursor1", chnInfo.right_value);
			jo1.put("time_diff", chnInfo.time_diff);
			jo1.put("ph", chnInfo.ph);
			if(null == chnInfo.chn_name){
			}else if(chnInfo.chn_name.indexOf("A")>-1 || chnInfo.chn_name.indexOf("a")>-1){
				jo1.put("ph", "A");
			}else if(chnInfo.chn_name.indexOf("B")>-1 || chnInfo.chn_name.indexOf("b")>-1){
				jo1.put("ph", "B");
			}else if(chnInfo.chn_name.indexOf("C")>-1 || chnInfo.chn_name.indexOf("c")>-1){
				jo1.put("ph", "C");
			}
			
			ja.add(jo1);
		}
		jo.put("ts", JSONArray.toJSON(dataInfo.times));
		jo.put("sampleInfo", JSONArray.toJSON(dataInfo.sampleInfo));
		jo.put("allSelector",JSONArray.toJSON(dataInfo.chnSelectInfo));
		jo.put("chns", ja);	
		return jo;
	}
	
}
